home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / SMISC.C < prev    next >
C/C++ Source or Header  |  1997-09-07  |  19KB  |  870 lines

  1. /* Miscellaneous Internet servers: discard, echo and remote
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "commands.h"
  6. #ifndef MSDOS
  7. #include <time.h>
  8. #endif
  9. #include "netuser.h"
  10. #include "remote.h"
  11. #include "smtp.h"
  12. #include "tcp.h"
  13. #include "nr4.h"
  14. #include "mailbox.h"
  15. #include "stats.h"
  16.  
  17. #if !defined(_lint)
  18. static char rcsid[] OPTIONAL = "$Id: smisc.c,v 1.31 1997/09/07 21:18:28 root Exp root $";
  19. #endif
  20.  
  21. char const *Rempass = "";    /* Remote access password */
  22. char const *RemRTpass = "";    /* Remote access password for adding routes */
  23.  
  24. extern char *MMotd;
  25.  
  26. #ifdef ALLSERV
  27. static void discserv (int s, void *unused, void *p);
  28. static void echoserv (int s, void *unused, void *p);
  29. static void quoteserv (int s, void *unused, void *p);
  30. static void timeserv (int s, void *unused, void *p);
  31. static void daytimeserv (int s, void *unused, void *p);
  32. static void handleserver (int s, const char *name, int type);
  33. #endif
  34.  
  35. static int chkrpass (struct mbuf * bp, int isaxip);
  36.  
  37. #ifdef TRACESERVER
  38. static void traceserv (int s, void *unused, void *p);
  39. #endif
  40.  
  41. #ifdef ALLSERV
  42. char *getquote (void);
  43. #endif
  44.  
  45. #ifdef TUTOR
  46. static void tutorserver (int s, void *mode, void *p);
  47. #endif
  48.  
  49. static const char deletenone[] = "The server is not active - nothing to stop!\n";
  50. static const char openstr[] = "open %s";
  51. static const char quotehdr[] = "\nQuote-of-the-Day at '%s' on %s\n";
  52. static const char failedstr[] = "%s failed";
  53. static const char closestr[] = "close %s";
  54. static const char discardlistener[] = "Discard listener";
  55. static const char discardserver[] = "Discard server";
  56. static const char discardstr[] = "discard";
  57. static const char timelistener[] = "Time listener";
  58. static const char timeserver[] = "Time server";
  59. static const char timestr[] = "time";
  60. static const char daytimelistener[] = "Daytime listener";
  61. static const char daytimeserver[] = "Daytime server";
  62. static const char daytimestr[] = "daytime";
  63. static const char echolistener[] = "Echo listener";
  64. static const char echoserver[] = "Echo server";
  65. static const char echostr[] = "echo";
  66. static const char tracelistener[] = "Trace listener";
  67. static const char traceserver[] = "Trace server";
  68. static const char opentrace[] = "open trace";
  69. static const char remotelistener[] = "Remote listener";
  70. static const char passwdfail[] = "PASSWORD FAIL";
  71. static const char remoteexit[] = "Remote exit %s %s";
  72. static const char remotekick[] = "Remote kick by %s for host %s";
  73. static const char remoteroute[] = "Remote route %s attempt from %s for '%s' %s";
  74. static const char quotelistener[] = "Quote listener";
  75. static const char quoteserver[] = "Quote server";
  76. static const char quotestr[] = "quote";
  77. static const char noopen[] = "Couldn't open '%s'\n";
  78. static const char telnetstr[] = "telnet";
  79.  
  80. #ifdef MSDOS
  81. static const char remotereset[] = "Remote reset %s %s";
  82. #endif
  83.  
  84. #ifdef RLOGINSERV
  85. static const char RLoginlistener[] = "RLogin listener";
  86. static const char RLoginserver[] = "RLogin server";
  87. #endif
  88.  
  89. #ifdef TUTOR
  90. static const char tutopen[] = "open %s server";
  91. static const char nonamestr[] = "noname";
  92. static const char tutclose[] = "close %s server";
  93. static const char tutorlistener[] = "Tutor listener";
  94. static const char Tutorserver[] = "Tutor server";
  95. static const char infolistener[] = "Info listener";
  96. static const char Infoserver[] = "Info server";
  97. static const char newslistener[] = "News listener";
  98. static const char Newsserver[] = "News server";
  99. #endif
  100.  
  101.  
  102. static int Rem = -1;
  103.  
  104.  
  105. void
  106. server_disconnect_io (void)
  107. {
  108.     if (Curproc->input != -1)    {
  109.         close_s (Curproc->input);
  110.         Curproc->input = -1;
  111.     }
  112.     if (Curproc->output != -1)    {
  113.         close_s (Curproc->output);
  114.         Curproc->output = -1;
  115.     }
  116. }
  117.  
  118.  
  119.  
  120. int
  121. deleteserver (int *mysocket)
  122. {
  123.     if (*mysocket != -1) {
  124.         close_s (*mysocket);
  125.         *mysocket = -1;
  126.     } else
  127.         tputs (deletenone);
  128.     return 0;
  129. }
  130.  
  131.  
  132.  
  133. /* Start up a TCP server */
  134. int
  135. installserver (
  136. int argc,
  137. char *argv[],
  138. int *mysocket,
  139. const char *listener,
  140. int defport,
  141. uint32 defaddress,
  142. const char *procname,
  143. void (*proc) (int, void *, void *),
  144. unsigned int size,
  145. void *parm
  146. ) {
  147. struct sockaddr_in lsocket;
  148. int s;
  149.  
  150.     if (*mysocket != -1)
  151.         return 0;
  152.  
  153.     ksignal (Curproc, 0);    /* Don't keep the parser waiting */
  154.     chname (Curproc, listener);
  155.  
  156.     lsocket.sin_family = AF_INET;
  157.     lsocket.sin_addr.s_addr = defaddress;
  158.     if (argc < 2)
  159.         lsocket.sin_port = (int16) defport;
  160.     else
  161.         lsocket.sin_port = (int16) atoi (argv[1]);
  162.     *mysocket = socket (AF_INET, SOCK_STREAM, 0);
  163.     (void) bind (*mysocket, (char *) &lsocket, sizeof (lsocket));
  164.     (void) listen (*mysocket, 1);
  165.     server_disconnect_io ();
  166.     for (;;) {
  167.         if ((s = accept (*mysocket, NULLCHAR, (int *) NULL)) == -1)
  168.             break;    /* Service is shutting down */
  169.  
  170.         /* Low mem check now done in tcpin.c - WG7J */
  171.         /* Spawn a server */
  172.         (void) newproc (procname, (unsigned int) size, proc, s, parm, NULL, 0);
  173.     }
  174.     return 0;
  175. }
  176.  
  177.  
  178.  
  179. #ifdef RLOGINSERV
  180. static int Srlogin = -1;
  181. #endif
  182.  
  183. #ifdef TRACESERVER
  184. static int Strace = -1;
  185. #endif
  186.  
  187. #ifdef TUTOR
  188. int Stutor = -1;
  189. int Sinfo = -1;
  190. int Snews = -1;
  191. #endif
  192.  
  193. #ifdef ALLSERV
  194. static int Sdisc = -1;
  195. static int Stime = -1;
  196. static int Squote = -1;
  197. static int Sdaytime = -1;
  198. static int Secho = -1;
  199.  
  200. #define DIFFTIME 2208988800LU
  201.  
  202. #define T_TIME         0
  203. #define T_DAYTIME    1
  204. #define    T_DISCARD    2
  205. #define T_ECHO        3
  206. #define T_QUOTE        4
  207.  
  208.  
  209.  
  210. static void
  211. handleserver (int s, const char *name, int type)
  212. {
  213. struct mbuf *bp;
  214. time_t currtime;
  215. char buf[32];
  216. long adjust;
  217. struct tm *tmp;
  218.  
  219.     (void) sockowner (s, Curproc);
  220.     sprintf (buf, openstr, name);
  221.     log (s, buf);
  222.     switch (type) {
  223.         case T_DISCARD:
  224.             while (recv_mbuf (s, &bp, 0, NULLCHAR, NULL) > 0)
  225.                 free_p (bp);
  226.             break;
  227.         case T_QUOTE:
  228.             {
  229.             char buf2[512], *cp;
  230.  
  231.                 cp = getquote ();
  232.                 currtime = time (&currtime);
  233.                 sprintf (buf2, quotehdr, Hostname, ctime (&currtime));
  234.                 bp = qdata ((unsigned char *) buf2, (int16) strlen (buf2));
  235.                 (void) send_mbuf (s, bp, 0, NULLCHAR, 0);
  236.                 bp = qdata ((unsigned char *) cp, (int16) strlen (cp));
  237.                 free (cp);
  238.             }
  239.             goto common;
  240.         case T_TIME:
  241.         case T_DAYTIME:
  242.             currtime = time (&currtime);
  243.             tmp = localtime (&currtime);
  244.             if (type == T_DAYTIME)        {    /* daytime protocol */
  245.                 (void) strftime (buf, 32, "%a %b %d, %Y %X %Z\n", tmp);
  246.                 bp = qdata ((unsigned char *) buf, (int16) strlen(buf));
  247.             } else {
  248.                 /*
  249.                  * Change 1970 start time to 1900 start time,
  250.                  * and put it in network order
  251.                  */
  252. #if defined(HAVE_TM_ISDST) && !defined(MSDOS)
  253.                 adjust = (timezone - (tmp->tm_isdst * 3600L)) / -1L;
  254. #else
  255.                 adjust = tmp->tm_gmtoff;
  256. #endif
  257.                 (void) put32 ((unsigned char *) buf, (uint32) (((uint32)currtime + DIFFTIME) + adjust));    /*lint !e737 */
  258.  
  259.                 /* enqueue for transmission */
  260.                 bp = qdata ((unsigned char *) buf, sizeof (int32));
  261.             }
  262. common:
  263.             if (send_mbuf (s, bp, 0, NULLCHAR, 0) == -1) {
  264.                 sprintf (buf, failedstr, name);
  265.                 log (s, buf);
  266.             }
  267.             break;
  268.         case T_ECHO:
  269.             while (recv_mbuf (s, &bp, 0, NULLCHAR, NULL) > 0)
  270.                 (void) send_mbuf (s, bp, 0, NULLCHAR, 0);
  271.             break;
  272.         default:
  273.             break;
  274.     }
  275.     sprintf (buf, closestr, name);
  276.     log (s, buf);
  277.     close_s (s);
  278. }
  279.  
  280.  
  281.  
  282. /* Start up TCP discard server */
  283. int
  284. dis1 (int argc, char *argv[], void *p OPTIONAL)
  285. {
  286.     return (installserver (argc, argv, &Sdisc, discardlistener, IPPORT_DISCARD,
  287.         INADDR_ANY, discardserver, discserv, 576, NULL));
  288. }
  289.  
  290.  
  291.  
  292. static void
  293. discserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
  294. {
  295. #ifdef STATS_USE
  296.     STATS_adduse (1);
  297.     MiscUsers++;
  298. #endif
  299.     handleserver (s, discardstr, T_DISCARD);
  300. #ifdef STATS_USE
  301.     MiscUsers--;
  302. #endif
  303. }
  304.  
  305.  
  306.  
  307. /* Stop discard server */
  308. int
  309. dis0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  310. {
  311.     return (deleteserver (&Sdisc));
  312. }
  313.  
  314.  
  315.  
  316. /* Start up TCP time server */
  317. int
  318. time1 (int argc, char *argv[], void *p OPTIONAL)
  319. {
  320.     return (installserver (argc, argv, &Stime, timelistener, IPPORT_TIME,
  321.         INADDR_ANY, timeserver, timeserv, 512, NULL));
  322. }
  323.  
  324.  
  325.  
  326. static void
  327. timeserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
  328. {
  329.     (void) sockmode (s, SOCK_BINARY);
  330.     handleserver (s, timestr, T_TIME);
  331. }
  332.  
  333.  
  334.  
  335. /* Stop time server */
  336. int
  337. time0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  338. {
  339.     return (deleteserver (&Stime));
  340. }
  341.  
  342.  
  343.  
  344. /* Start up TCP daytime server */
  345. int
  346. daytime1 (int argc, char *argv[], void *p OPTIONAL)
  347. {
  348.     return (installserver (argc, argv, &Sdaytime, daytimelistener, IPPORT_DAYTIME,
  349.         INADDR_ANY, daytimeserver, daytimeserv, 576, NULL));
  350. }
  351.  
  352.  
  353.  
  354. static void
  355. daytimeserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
  356. {
  357.     handleserver (s, daytimestr, T_DAYTIME);
  358. }
  359.  
  360.  
  361.  
  362. /* Stop time server */
  363. int
  364. daytime0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  365. {
  366.     return (deleteserver (&Sdaytime));
  367. }
  368.  
  369.  
  370.  
  371. /* Start up TCP echo server */
  372. int
  373. echo1 (int argc, char *argv[], void *p OPTIONAL)
  374. {
  375.     return (installserver (argc, argv, &Secho, echolistener, IPPORT_ECHO,
  376.         INADDR_ANY, echoserver, echoserv, 2048, NULL));
  377. }
  378.  
  379.  
  380.  
  381. static void
  382. echoserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
  383. {
  384. #ifdef STATS_USE
  385.     STATS_adduse (1);
  386.     MiscUsers++;
  387. #endif
  388.     handleserver (s, echostr, T_ECHO);
  389. #ifdef STATS_USE
  390.     MiscUsers--;
  391. #endif
  392. }
  393.  
  394.  
  395.  
  396. /* stop echo server */
  397. int
  398. echo0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  399. {
  400.     return (deleteserver (&Secho));
  401. }
  402. #endif /*ALLSERV*/
  403.  
  404.  
  405.  
  406.  
  407. #if defined(TRACESERVER) || defined(ENCAP)
  408. extern struct cmds Cmds[];
  409. #endif
  410.  
  411.  
  412. #ifdef TRACESERVER
  413.  
  414. /* Start up TCP trace server */
  415. int
  416. trace1 (int argc, char *argv[], void *p OPTIONAL)
  417. {
  418.     return (installserver (argc, argv, &Strace, tracelistener, IPPORT_TRACE,
  419.         INADDR_ANY, traceserver, traceserv, 1024, NULL));
  420. }
  421.  
  422.  
  423.  
  424. /* Stop trace server */
  425. int
  426. trace0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  427. {
  428.     return (deleteserver (&Strace));
  429. }
  430.  
  431.  
  432.  
  433. static void
  434. traceserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
  435. {
  436. #define CMDLINE 80
  437. char *cmd;
  438. int outsave, insave;
  439.  
  440. #ifdef STATS_USE
  441.     STATS_adduse (1);
  442.     MiscUsers++;
  443. #endif
  444.     (void) sockowner (s, Curproc);
  445.     log (s, opentrace);
  446.     outsave = Curproc->output;
  447.     Curproc->output = s;
  448.     insave = Curproc->input;
  449.     Curproc->input = s;
  450.  
  451.     /* allocate the command buffer */
  452.     cmd = mallocw (CMDLINE + 1);
  453.  
  454.     while (recvline (s, (unsigned char *) cmd, CMDLINE) > 0) {
  455.         if (!strnicmp ("tr", cmd, 2))    /* only allow 'trace' command ! */
  456.             (void) cmdparse (Cmds, cmd, NULL);
  457.         if (!strnicmp ("ex", cmd, 2))
  458.             break;
  459.     }
  460.     removetrace ();
  461.     Curproc->input = insave;
  462.     Curproc->output = outsave;
  463.     log (s, "close trace");
  464. #ifdef STATS_USE
  465.     MiscUsers--;
  466. #endif
  467.     close_s (s);
  468. }
  469. #endif /* TRACESERVER */
  470.  
  471.  
  472.  
  473. /* Start remote exit/reboot server */
  474. int
  475. rem1 (int argc, char *argv[], void *p OPTIONAL)
  476. {
  477. struct sockaddr_in lsocket, fsock;
  478. int i;
  479. int command;
  480. struct mbuf *bp, **bpp;
  481. uint32 addr;
  482. char temp[80], cmdbuf[128];
  483. int len;
  484. int action;
  485. char *ab, *cp;
  486. int badaddr;
  487.  
  488.     if (Rem != -1)
  489.         return 0;
  490.     ksignal (Curproc, 0);
  491.     chname (Curproc, remotelistener);
  492.     server_disconnect_io ();
  493.     lsocket.sin_family = AF_INET;
  494.     lsocket.sin_addr.s_addr = INADDR_ANY;
  495.     if (argc < 2)
  496.         lsocket.sin_port = IPPORT_REMOTE;
  497.     else
  498.         lsocket.sin_port = (int16) atoi (argv[1]);
  499.  
  500.     Rem = socket (AF_INET, SOCK_DGRAM, 0);
  501.     (void) bind (Rem, (char *) &lsocket, sizeof (lsocket));
  502.     for (;;) {
  503.         i = sizeof (fsock);
  504.         if (recv_mbuf (Rem, &bp, 0, (char *) &fsock, &i) == -1)
  505.             break;
  506.         bpp = &bp;
  507.         command = PULLCHAR (bpp);
  508.  
  509.         switch (command) {
  510. #ifdef    MSDOS            /* Only present on PCs running MSDOS */
  511.             case SYS_RESET:
  512.                 i = chkrpass (bp, 0);
  513.                 log (Rem, remotereset, psocket ((struct sockaddr *) &fsock),
  514.                      i == 0 ? passwdfail : "");
  515.                 if (i != 0) {
  516.                     /*Indicate a hardware reset*/
  517.                     where_outta_here (2, "rem1");
  518.                 }
  519.                 break;
  520. #endif
  521.             case SYS_EXIT:
  522.                 i = chkrpass (bp, 0);
  523.                 log (Rem, remoteexit, psocket ((struct sockaddr *) &fsock), (i == 0) ? passwdfail : "");
  524.                 if (i != 0)     /*No reset*/
  525.                     where_outta_here (0, "rem1");
  526.                 break;
  527.             case KICK_ME:
  528.                 if (len_p (bp) >= sizeof (int32))
  529.                     addr = pull32 (&bp);
  530.                 else
  531.                     addr = fsock.sin_addr.s_addr;
  532.  
  533.                 /* get round strange printf bug */
  534.                 strncpy (temp, inet_ntoa (addr), 20);
  535.  
  536.                 log (Rem, remotekick, psocket ((struct sockaddr *) &fsock), temp);
  537. #ifdef NETROM
  538.                 donodetick ();    /* g3rra's idea!..hmmm */
  539. #endif /* NETROM */
  540.                 (void) kick (addr);
  541.                 smtptick ((void *) addr);
  542.                 break;
  543. #ifdef ENCAP
  544.             case ROUTE_ADD:
  545.             case ROUTE_DROP:
  546.                 action = (command == ROUTE_ADD) ? 1 : 0;
  547.  
  548.                 /* first, extract the route string */
  549.                 len = PULLCHAR (bpp);    /* get the length of the name portion */
  550.                 if (len > 18)
  551.                     break;
  552.                 (void) pullup (bpp, (unsigned char *) temp, (int16) len);
  553.                 temp[len] = 0;
  554.  
  555.                 /* now check the password */
  556.                 i = chkrpass (bp, 1);
  557.  
  558.                 ab = psocket ((struct sockaddr *) &fsock);
  559.                 if ((cp = strchr (ab, ':')) != NULLCHAR)
  560.                     *cp = 0;
  561.                 badaddr = (strcmp (ab, "127.0.0.1")) ? 0 : 1;
  562.                 if (badaddr && action)
  563.                     tcmdprintf ("Attempt to add remote route to 127.0.0.1 - ignored\n");
  564.  
  565.                 log (Rem, remoteroute, (action) ? "add" : "drop", ab, temp, (badaddr) ? "cannot route to 127.0.0.1" : (i == 0) ? passwdfail : "");
  566.  
  567.                 if (strncmp (temp, "44.", 3) || !strncmp (ab, "44.", 3) || aton(temp) == 0)
  568.                     i = 0;        /* disable if route not for amprnet or from amprnet (error) */
  569.     
  570.                 if (i != 0)    {
  571.                     /* add/drop the route */
  572.                     if (action)
  573.                         sprintf (cmdbuf, "route addp %s encap %s", temp, ab);
  574.                     else
  575.                         sprintf (cmdbuf, "route drop %s", temp);
  576.                     (void) cmdparse (Cmds, cmdbuf, NULL);
  577.                 }
  578.                 break;
  579. #endif
  580.             default:
  581.                 break;
  582.         }
  583. #if 0    /* deliberate memory leak */
  584.         free_p (bp);
  585. #endif
  586.     }
  587.     close_s (Rem);
  588.     Rem = -1;
  589.     return 0;
  590. }
  591.  
  592.  
  593.  
  594. /* Check remote password */
  595. static int
  596. chkrpass (struct mbuf *bp, int isaxip)
  597. {
  598. char *lbuf;
  599. int16 len;
  600. int rval = 0;
  601.  
  602.     len = len_p (bp);
  603.     if (!isaxip)    {
  604.         if (strlen (Rempass) == 0 || strlen (Rempass) != len)
  605.             return rval;
  606.     } else {
  607.         if (strlen (RemRTpass) == 0 || strlen (RemRTpass) != len)
  608.             return rval;
  609.     }
  610.     lbuf = mallocw (len);
  611.     (void) pullup (&bp, (unsigned char *) lbuf, len);
  612.     if (strncmp ((!isaxip) ? Rempass : RemRTpass, lbuf, len) == 0)
  613.         rval = 1;
  614.     free (lbuf);
  615.     return rval;
  616. }
  617.  
  618.  
  619.  
  620. int
  621. rem0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  622. {
  623.     close_s (Rem);
  624.     return 0;
  625. }
  626.  
  627.  
  628.  
  629. #ifdef ALLSERV
  630. /* Start up TCP quote server */
  631. int
  632. quote1 (int argc, char *argv[], void *p OPTIONAL)
  633. {
  634.     return (installserver (argc, argv, &Squote, quotelistener, IPPORT_QUOTE,
  635.         INADDR_ANY, quoteserver, quoteserv, 1536, NULL));
  636. }
  637.  
  638.  
  639.  
  640. static void
  641. quoteserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
  642. {
  643.     handleserver (s, quotestr, T_QUOTE);
  644. }
  645.  
  646.  
  647.  
  648. /* Stop quote server */
  649. int
  650. quote0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  651. {
  652.     return (deleteserver (&Squote));
  653. }
  654.  
  655.  
  656.  
  657. char *
  658. getquote ()
  659. {
  660. char buf2[512];
  661. char searchstr[8];
  662. char buf3[4096];
  663. char *cptr;
  664. FILE *fp;
  665. struct date dt;
  666.  
  667.     if (Squote == -1)
  668.         return (NULLCHAR);
  669.     if ((fp = fopen (Quotes, READ_TEXT)) == NULLFILE) {
  670.         if (MMotd != NULLCHAR)
  671.             return (strdup (MMotd));
  672.         else
  673.             return (NULLCHAR);
  674.     }
  675.     tnos_getdate (&dt);
  676.     sprintf (searchstr, "[%-d]", dt.da_day);
  677.     while (fgets (buf2, 512, fp) != NULLCHAR) {
  678.         if (!strncmp (searchstr, buf2, strlen (searchstr)))
  679.             break;
  680.     }
  681.     buf3[0] = 0;
  682.     if ((cptr = strchr (buf2, '%')) != NULLCHAR) {
  683.         rip (buf2);
  684.         (void) fclose (fp);
  685.         if ((fp = fopen (++cptr, READ_TEXT)) == NULLFILE) {
  686.             tcmdprintf (noopen, &buf2[1]);
  687.             return (NULLCHAR);
  688.         }
  689.     }
  690.     while (fgets (buf2, 512, fp) != NULLCHAR) {
  691.         if (*buf2 == '[')
  692.             break;
  693.         strcat (buf3, buf2);
  694.     }
  695.     (void) fclose (fp);
  696.     return (strdup (buf3));
  697. }
  698. #endif /* ALLSERV */
  699.  
  700.  
  701.  
  702. /* Execute user quote command */
  703. int
  704. doquote (int argc OPTIONAL, char *argv[], void *p)
  705. {
  706.     free (argv[0]);
  707.     argv[0] = strdup (telnetstr);
  708.     if (argv[2])
  709.         free (argv[2]);
  710.     argv[2] = strdup ("17");
  711.     if (!argv[1])
  712.         argv[1] = strdup (Hostname);
  713.     return dotelnet (3, argv, p);
  714. }
  715.  
  716.  
  717.  
  718. #ifdef RLOGINSERV
  719. /* Start up RLOGIN server */
  720. int
  721. rlogin1 (int argc, char *argv[], void *p OPTIONAL)
  722. {
  723.     return (installserver (argc, argv, &Srlogin, RLoginlistener, IPPORT_RLOGIN,
  724.         INADDR_ANY, RLoginserver, pbbs_incom, 2048, (void *) RLOGIN_LINK));
  725. }
  726.  
  727.  
  728.  
  729. /* Stop RLOGIN server */
  730. int
  731. rlogin0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  732. {
  733.     return (deleteserver (&Srlogin));
  734. }
  735. #endif
  736.  
  737.  
  738.  
  739. #ifdef TUTOR
  740. extern void tutorserv (const char *, struct mbx *, int, int, int);
  741. static const char *tut[] = {"tutor", "info", "news"};
  742.  
  743.  
  744.  
  745. static void
  746. tutorserver (int s, void *mode, void *p OPTIONAL)
  747. {
  748. int outsave, insave;
  749.  
  750.     (void) sockmode (s, SOCK_ASCII);
  751.     (void) sockowner (s, Curproc);
  752.     log (s, tutopen, tut[(int) mode]);
  753.     outsave = Curproc->output;
  754.     Curproc->output = s;
  755.     insave = Curproc->input;
  756.     Curproc->input = s;
  757.     tutorserv (nonamestr, NULLMBX, (int) mode, 0, 1);
  758.     Curproc->input = insave;
  759.     Curproc->output = outsave;
  760.     log (s, tutclose, tut[(int) mode]);
  761.     close_s (s);
  762. }
  763.  
  764.  
  765.  
  766. /* Start up TCP tutorial server */
  767. int
  768. tutor1 (int argc, char *argv[], void *p OPTIONAL)
  769. {
  770.     return (installserver (argc, argv, &Stutor, tutorlistener, IPPORT_TUTOR,
  771.         INADDR_ANY, Tutorserver, tutorserver, 2048, (void *) 0));
  772. }
  773.  
  774.  
  775.  
  776. /* Stop tutorial server */
  777. int
  778. tutor0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  779. {
  780.     return (deleteserver (&Stutor));
  781. }
  782.  
  783.  
  784.  
  785. /* Start up TCP tutorial server */
  786. int
  787. info1 (int argc, char *argv[], void *p OPTIONAL)
  788. {
  789.     return (installserver (argc, argv, &Sinfo, infolistener, IPPORT_INFO,
  790.         INADDR_ANY, Infoserver, tutorserver, 2048, (void *) 1));
  791. }
  792.  
  793.  
  794.  
  795. /* Stop tutorial server */
  796. int
  797. info0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  798. {
  799.     return (deleteserver (&Sinfo));
  800. }
  801.  
  802.  
  803.  
  804. /* Start up TCP news server */
  805. int
  806. news1 (int argc, char *argv[], void *p OPTIONAL)
  807. {
  808.     return (installserver (argc, argv, &Snews, newslistener, IPPORT_NEWS,
  809.         INADDR_ANY, Newsserver, tutorserver, 2048, (void *) 2));
  810. }
  811.  
  812.  
  813.  
  814. /* Stop news server */
  815. int
  816. news0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  817. {
  818.     return (deleteserver (&Snews));
  819. }
  820.  
  821.  
  822.  
  823. static char WhichTutor = 0;
  824.  
  825.  
  826.  
  827. /* Execute user tutor command */
  828. int
  829. dotutor (int argc OPTIONAL, char *argv[], void *p)
  830. {
  831. char buf[6];
  832. int i = WhichTutor;
  833.  
  834.     WhichTutor = 0;
  835.     free (argv[0]);
  836.     argv[0] = strdup (telnetstr);
  837.     if (argv[2])
  838.         free (argv[2]);
  839.     sprintf (buf, "%-d", IPPORT_TUTOR - i);
  840.     argv[2] = strdup (buf);
  841.     if (!argv[1])
  842.         argv[1] = strdup (Hostname);
  843.     return dotelnet (3, argv, p);
  844. }
  845.  
  846.  
  847.  
  848. /* Execute user info command */
  849. int
  850. doinfo (int argc, char *argv[], void *p)
  851. {
  852.     WhichTutor = 1;
  853.     return (dotutor (argc, argv, p));
  854. }
  855.  
  856.  
  857.  
  858. /* Execute user info command */
  859. int
  860. donews (int argc, char *argv[], void *p)
  861. {
  862.     WhichTutor = 2;
  863.     return (dotutor (argc, argv, p));
  864. }
  865.  
  866.  
  867. #endif
  868.  
  869.  
  870.